use async_std::{net::TcpStream, stream::StreamExt};
use chrono::{DateTime, Utc};
use mailparse::{parse_mail, MailHeaderMap};

use crate::EmailHeader;

#[tauri::command]
pub async fn get_email_body(id:String) -> String{
    let server = ("imap.163.com",993);
    let tcp = TcpStream::connect(server).await.unwrap();
    let tls = async_native_tls::TlsConnector::new();
    let tls_stream = tls.connect("imap.163.com", tcp).await.unwrap();
    let client = async_imap::Client::new(tls_stream);

    let mut session = client.login("zenghaifenghandsom@163.com", "QDunvLP8Vrnhn5hJ").await.unwrap();
    
    let idstr = vec!(("name", Some("zenghaifeng")),("version", Some("1.0.0")),("vendor", Some("myclient")),("support-email", Some("zenghaifenghandsom@163.com"))); // (, ,, );
    
    session.id(idstr).await.unwrap();

    let _ = session.select("inbox").await.unwrap();
    let email = session.fetch(id, "RFC822").await.unwrap();
    let email:Vec<_> = email.collect().await;
    let email = email.first().unwrap().as_ref().unwrap();

    let email = email.body().unwrap();
    //println!("{}",std::str::from_utf8(email).unwrap().to_string());
    let email = parse_mail(email).unwrap().subparts[0].get_body().unwrap();
    email
    // match email {
    //     Ok(e) => e,
    //     Err(e) => e.to_string()
    // }

}

#[tokio::test]
async fn test_email_body(){
    let result = get_email_body("1".to_string()).await;
    println!("result: {result}");
}

#[tauri::command]
pub async fn batch_email(starts:u32,ends:u32) ->Vec<EmailHeader>{
    let mut email_list:Vec<EmailHeader> = Vec::new();
    let server = ("imap.163.com",993);
    let tcp = TcpStream::connect(server).await.unwrap();
    let tls = async_native_tls::TlsConnector::new();
    let tls_stream = tls.connect("imap.163.com", tcp).await.unwrap();
    let client = async_imap::Client::new(tls_stream);

    let mut session = client.login("zenghaifenghandsom@163.com", "QDunvLP8Vrnhn5hJ").await.unwrap();
    
    let idstr = vec!(("name", Some("zenghaifeng")),("version", Some("1.0.0")),("vendor", Some("myclient")),("support-email", Some("zenghaifenghandsom@163.com"))); // (, ,, );
    
    session.id(idstr).await.unwrap();

    let s = session.select("inbox").await.unwrap();

    let mut start:u32 = starts.clone();
    let num = s.exists;
    //BODY[HEADER.FIELDS (FROM TO DATE SUBJECT)]  RFC822
    let email = session.fetch(format!("{starts}:{ends}"), "BODY[HEADER.FIELDS (FROM TO DATE SUBJECT)]").await.unwrap();
    let email:Vec<_> = email.collect().await;

    for e in email {
        match e {
            Ok(e) => {
                let mut email_header = EmailHeader::new(start,num);
                start +=1;
                let em = e.header().unwrap();
                let ps = parse_mail(em).unwrap();
                
                let subject = ps.headers.get_first_value("Subject").unwrap();
                let from = ps.headers.get_first_value("From").unwrap();
                let to = ps.headers.get_first_value("To").unwrap();
                let date = ps.headers.get_first_value("Date").unwrap();
                let date:Vec<_> = date.split("(").collect();
                let date = date.get(0).unwrap().trim();
                //println!("{date}");
                let date = DateTime::parse_from_str(&date,"%a, %d %b %Y %H:%M:%S %z").unwrap();

                let date = date.with_timezone(&Utc).format("%Y-%m-%d").to_string();

                email_header.subject=Some(subject);
                email_header.from=Some(from);
                email_header.to=Some(to);
                email_header.date=Some(date);

                //println!("{:#?}",email_header);
                email_list.push(email_header);
                
            },
            Err(_) => return vec![],
        }
    }

    session.logout().await.unwrap();
    email_list
}



#[tauri::command]
pub async fn get_email_body_once(id:String) ->Option<EmailHeader>{
    let mut email_list:Vec<EmailHeader> = Vec::new();
    let server = ("imap.163.com",993);
    let tcp = TcpStream::connect(server).await.unwrap();
    let tls = async_native_tls::TlsConnector::new();
    let tls_stream = tls.connect("imap.163.com", tcp).await.unwrap();
    let client = async_imap::Client::new(tls_stream);

    let mut session = client.login("zenghaifenghandsom@163.com", "QDunvLP8Vrnhn5hJ").await.unwrap();
    
    let idstr = vec!(("name", Some("zenghaifeng")),("version", Some("1.0.0")),("vendor", Some("myclient")),("support-email", Some("zenghaifenghandsom@163.com"))); // (, ,, );
    
    session.id(idstr).await.unwrap();

    let s = session.select("inbox").await.unwrap();

    let mut start:u32 = id.parse::<u32>().unwrap();
    let num = s.exists;
    //BODY[HEADER.FIELDS (FROM TO DATE SUBJECT)]  RFC822
    let email = session.fetch(id, "BODY[HEADER.FIELDS (FROM TO DATE SUBJECT)]").await.unwrap();
    let email:Vec<_> = email.collect().await;

    for e in email {
        match e {
            Ok(e) => {
                let mut email_header = EmailHeader::new(start,num);
                start +=1;
                let em = e.header().unwrap();
                let ps = parse_mail(em).unwrap();
                
                let subject = ps.headers.get_first_value("Subject").unwrap();
                let from = ps.headers.get_first_value("From").unwrap();
                let to = ps.headers.get_first_value("To").unwrap();
                let date = ps.headers.get_first_value("Date").unwrap();
                let date:Vec<_> = date.split("(").collect();
                let date = date.get(0).unwrap().trim();
                //println!("{date}");
                let date = DateTime::parse_from_str(&date,"%a, %d %b %Y %H:%M:%S %z").unwrap();

                let date = date.with_timezone(&Utc).format("%Y-%m-%d").to_string();

                email_header.subject=Some(subject);
                email_header.from=Some(from);
                email_header.to=Some(to);
                email_header.date=Some(date);

                //println!("{:#?}",email_header);
                email_list.push(email_header);
                
            },
            Err(_) => return None,
        }
    }

    session.logout().await.unwrap();
    let result = email_list.get(0).unwrap();
    Some(result.clone())
}